package com.example.freemaker_demo.executer.impl;


import cn.hutool.core.util.StrUtil;
import com.example.freemaker_demo.constant.ConstantUtil;
import com.example.freemaker_demo.entity.JavaTplEntity;
import com.example.freemaker_demo.executer.TemplateReplacer;
import com.example.freemaker_demo.tools.FreemakerTool;
import com.example.freemaker_demo.tools.TemplateTool;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.Map;

@Data
@Accessors(chain = true)
public class JavaTemplateReplacerImpl implements TemplateReplacer {

    private JavaTplEntity javaTplEntity;

    private Map<String, Object> dockerfileMapper = new HashMap<>();
    private Map<String, Object> runShMapper = new HashMap<>();
    private Map<String, Object> jenkinsfileMapper = new HashMap<>();
    private Map<String, Object> kubeYamlMapper = new HashMap<>();
    private Map<String, Object> bootStrapMapper = new HashMap<>();
    private Map<String, Object> jibFilesMapper = new HashMap<>();
    private Map<String, Object> logbackMapper = new HashMap<>();

    String templateOutputPath;
    String loopTemplateOutputPath;


    @Override
    public void doReplace(String outputDir) {
        templateOutputPath = outputDir;
        loopTemplateOutputPath = templateOutputPath
                + "javaTpl/"
                + javaTplEntity.getContainer().getImageName()
                + "/";

        if ("jib".equals(javaTplEntity.getMode())) {
            doReplaceJibFiles();
        } else {
            doReplaceDockerfile();
        }
        doReplaceRunSh();
        doReplaceJenkinsfile();
        doReplaceK8sFiles();
        doReplaceBootstrap();
        doReplaceLogback();
    }

    private void doReplaceDockerfile() {
        prepareDockerfile();
        replaceDockerfile();
    }

    private void doReplaceRunSh() {
        prepareRunSh();
        replaceRunSh();
    }

    private void doReplaceJenkinsfile() {
        prepareJenkinsfileProd();
        replaceJenkinsfileProd();
        prepareJenkinsfileTest();
        replaceJenkinsfileTest();
    }

    private void doReplaceK8sFiles() {
        prepareK8sFilesProd();
        replaceK8sFilesProd();
        prepareK8sFilesTest();
        replaceK8sFilesTest();
    }

    private void doReplaceBootstrap() {
        prepareBootstrapProd();
        replaceBootstrapProd();
        prepareBootstrapTest();
        replaceBootstrapTest();
    }

    private void doReplaceJibFiles() {
        prepareJibFiles();
        replaceJibFiles();
    }

    private void doReplaceLogback() {
        prepareLogback();
        replaceLogback();
    }


    private void prepareDockerfile() {
        dockerfileMapper.put("jarName", javaTplEntity.getContainer().getJarName());
        dockerfileMapper.put("moduleName", javaTplEntity.getMaven().getModuleName());
        dockerfileMapper.put("mode", javaTplEntity.getMode() == null ? "" : javaTplEntity.getMode());

    }

    private void replaceDockerfile() {
        if (ConstantUtil.multiMode.equals(javaTplEntity.getMode())) {
            FreemakerTool.generateFile(loopTemplateOutputPath + "/" + "Dockerfile",
                    "Dockerfile.java.ftl",
                    dockerfileMapper);
        } else {
            FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/" + "Dockerfile",
                    "Dockerfile.java.ftl",
                    dockerfileMapper);
        }
    }

    private void prepareRunSh() {
        runShMapper.put("mode", javaTplEntity.getMode() == null ? "" : javaTplEntity.getMode());
        if ("jib".equals(javaTplEntity.getMode())) {
            runShMapper.put("mainClass", javaTplEntity.getMaven().getMainClass());
        } else {
            runShMapper.put("jarName", javaTplEntity.getContainer().getJarName());
        }
    }

    private void replaceRunSh() {
        if ("jib".equals(javaTplEntity.getMode())) {
            FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/src/main/jib/run.sh",
                    "run.sh.ftl",
                    runShMapper);
        } else {
            FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/run.sh",
                    "run.sh.ftl",
                    runShMapper);
        }
    }

    private void prepareJenkinsfileProd() {
        String kubeConfig = TemplateTool.getKubeConfig(javaTplEntity.getK8s().getCluster());
        String allImageName = TemplateTool.getRepoAddress(javaTplEntity.getK8s().getCluster());
        String tagsCommand = TemplateTool.prepareTagsCommand(javaTplEntity.getContainer().getExtraTag().getTagName(),
                javaTplEntity.getContainer().getExtraTag().getEnable(),false);

        jenkinsfileMapper.put("sedScript", "");
        jenkinsfileMapper.put("moduleName", javaTplEntity.getMaven().getModuleName());
        jenkinsfileMapper.put("imageName", ConstantUtil.ACRAddress + "/softwise/" + javaTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("tagCommand", tagsCommand);
        jenkinsfileMapper.put("mode", javaTplEntity.getMode() == null ? "" : javaTplEntity.getMode());
        jenkinsfileMapper.put("cluster", javaTplEntity.getK8s().getCluster());
        jenkinsfileMapper.put("env", "prod" + "/" + javaTplEntity.getMaven().getModuleName());
        jenkinsfileMapper.put("yamlFile", javaTplEntity.getK8s().getDeployName() + "-deploy.yaml");
        jenkinsfileMapper.put("namespace", javaTplEntity.getK8s().getNamespace());
        jenkinsfileMapper.put("deploymentName", javaTplEntity.getK8s().getDeployName());
        jenkinsfileMapper.put("msg", javaTplEntity.getDingMsg());
        jenkinsfileMapper.put("kubeconfig", kubeConfig);
        jenkinsfileMapper.put("allImageName", allImageName + javaTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("k8sYamlDir", javaTplEntity.getK8s().getK8sYamlDir());
        jenkinsfileMapper.put("repoCredential", "acr-repo");
        jenkinsfileMapper.put("dockerRepoAddress", ConstantUtil.ACRAddress);
        jenkinsfileMapper.put("tags", StrUtil.join(",", javaTplEntity.getContainer().getExtraTag().getTagName()));
    }

    private void prepareJenkinsfileTest() {
        String testYamlDir = javaTplEntity.getK8s().getK8sYamlDir().replace("prod", "test");
        String allImageName = TemplateTool.getRepoAddress(javaTplEntity.getK8s().getCluster());
        String tagsCommand = TemplateTool.prepareTagsCommand(javaTplEntity.getContainer().getExtraTag().getTagName(),
                javaTplEntity.getContainer().getExtraTag().getEnable(), true);

        jenkinsfileMapper.put("imageName", ConstantUtil.harborAddress + "/softwise/" + javaTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("kubeconfig", ConstantUtil.internalKubeConfig);
        jenkinsfileMapper.put("tagCommand", tagsCommand);
        jenkinsfileMapper.put("sedScript", "sh 'sed -i \\'s/active: prod/active: test/\\' "
                + javaTplEntity.getMaven().getModuleName() + "/src/main/resources/bootstrap.yml'");
        jenkinsfileMapper.put("env", "test" + "/" + javaTplEntity.getMaven().getModuleName());
        jenkinsfileMapper.put("cluster", "internal");
        jenkinsfileMapper.put("k8sYamlDir", testYamlDir);
        jenkinsfileMapper.put("allImageName", allImageName + javaTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("repoCredential", "internal-harbor");
        jenkinsfileMapper.put("dockerRepoAddress", ConstantUtil.harborAddress);
    }

    private void replaceJenkinsfileProd() {
        FreemakerTool.generateFile(loopTemplateOutputPath + "Jenkinsfile-" + javaTplEntity.getMaven().getModuleName(),
                "Jenkinsfile.java.v2.ftl",
                jenkinsfileMapper);
    }

    private void replaceJenkinsfileTest() {
        FreemakerTool.generateFile(loopTemplateOutputPath + "Jenkinsfile-" + javaTplEntity.getMaven().getModuleName() + "-test",
                "Jenkinsfile.java.v2.ftl",
                jenkinsfileMapper);
    }

    private void prepareK8sFilesProd() {
        kubeYamlMapper.put("deployName", javaTplEntity.getK8s().getDeployName());
        kubeYamlMapper.put("kubesphereDescription", javaTplEntity.getDingMsg());
        kubeYamlMapper.put("namespace", javaTplEntity.getK8s().getNamespace());
        kubeYamlMapper.put("ingressName", javaTplEntity.getK8s().getDeployName());
        kubeYamlMapper.put("svcName", "common-gateway");

        // 正式环境的domain和ingressPath
        // 需要生成Ingress文件
        if (javaTplEntity.getK8s().getIngress().getEnable()) {
            kubeYamlMapper.put("domain", javaTplEntity.getK8s().getIngress().getDomainProd());
            if (javaTplEntity.getK8s().getIngress().getPrefixProd().equals("/")) {
                kubeYamlMapper.put("path", javaTplEntity.getK8s().getIngress().getPrefixProd());
                kubeYamlMapper.put("nginxRewrite", "");
            } else {
                kubeYamlMapper.put("path", javaTplEntity.getK8s().getIngress().getPrefixProd() + "(/|$)(.*)");
                kubeYamlMapper.put("nginxRewrite", "nginx.ingress.kubernetes.io/rewrite-target: /$2");
            }
        }
    }

    private void prepareK8sFilesTest() {
        if (javaTplEntity.getK8s().getIngress().getEnable()) {
            kubeYamlMapper.put("domain", javaTplEntity.getK8s().getIngress().getDomainTest());
            if (javaTplEntity.getK8s().getIngress().getPrefixTest().equals("/")) {
                kubeYamlMapper.put("path", javaTplEntity.getK8s().getIngress().getPrefixTest());
                kubeYamlMapper.put("nginxRewrite", "");
            } else {
                kubeYamlMapper.put("path", javaTplEntity.getK8s().getIngress().getPrefixTest() + "(/|$)(.*)");
                kubeYamlMapper.put("nginxRewrite", "nginx.ingress.kubernetes.io/rewrite-target: /$2");
            }
        }
    }

    private void replaceK8sFilesProd() {
        String k8sFileOutputPath = loopTemplateOutputPath + "kube-yaml" + "/";
        String prodFilePath = k8sFileOutputPath + "prod/" + javaTplEntity.getMaven().getModuleName() + "/";

        // 正式环境的domain和ingressPath
        // 需要生成Ingress文件
        if (javaTplEntity.getK8s().getIngress().getEnable()) {
            // ingress文件
            FreemakerTool.generateFile(prodFilePath + javaTplEntity.getK8s().getDeployName() + "-ingress.yaml",
                    "ingress.java.ftl",
                    kubeYamlMapper);
        }
        // deployment文件
        FreemakerTool.generateFile(prodFilePath + javaTplEntity.getK8s().getDeployName() + "-deploy.yaml",
                "deployment.java.ftl",
                kubeYamlMapper);
    }

    private void replaceK8sFilesTest() {
        String k8sFileOutputPath = loopTemplateOutputPath + "kube-yaml" + "/";
        String testFilePath = k8sFileOutputPath + "test/" + javaTplEntity.getMaven().getModuleName() + "/";

        if (javaTplEntity.getK8s().getIngress().getEnable()) {
            FreemakerTool.generateFile(testFilePath + javaTplEntity.getK8s().getDeployName() + "-ingress.yaml",
                    "ingress.java.ftl",
                    kubeYamlMapper);
        }
        // deployment文件
        FreemakerTool.generateFile(testFilePath + javaTplEntity.getK8s().getDeployName() + "-deploy.yaml",
                "deployment.java.ftl",
                kubeYamlMapper);
    }

    private void prepareBootstrapProd() {
        bootStrapMapper.put("appName", javaTplEntity.getMaven().getAppName());
        bootStrapMapper.put("profileName", "prod");
        bootStrapMapper.put("nacosAddr", javaTplEntity.getMaven().getProd().get("nacosAddr"));
        bootStrapMapper.put("nacosNamespace", javaTplEntity.getMaven().getProd().get("nacosNamespace"));
    }

    private void replaceBootstrapProd() {
        FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/src/main/resources/bootstrap-prod.yml",
                "bootstrap.yml.ftl",
                bootStrapMapper);
    }

    private void prepareBootstrapTest() {
        bootStrapMapper.put("profileName", "test");
    }

    private void replaceBootstrapTest() {
        FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/src/main/resources/bootstrap-test.yml",
                "bootstrap.yml.ftl",
                bootStrapMapper);
    }

    private void prepareJibFiles() {
        jibFilesMapper.put("imageName", ConstantUtil.ACRAddress + "/" + javaTplEntity.getContainer().getImageName());
        jibFilesMapper.put("mainClass", javaTplEntity.getMaven().getMainClass());
    }

    private void replaceJibFiles() {
        FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/pom.xml",
                "pom.xml.ftl",
                jibFilesMapper);
    }

    private void prepareLogback() {
        logbackMapper.put("moduleName", javaTplEntity.getMaven().getModuleName());
    }

    private void replaceLogback() {
        FreemakerTool.generateFile(loopTemplateOutputPath + javaTplEntity.getMaven().getModuleName() + "/src/main/resources/logback-spring.xml",
                "logback-spring.xml.ftl",
                logbackMapper);
    }
}